﻿@* QUnit-Razor NuGet package v0.2
 * http://www.nuget.org/packages/QUnit.Razor
 *
 * Adds QUnit js/css to ASP.NET MVC Razor projects and Cshtml Test Runner web page to /QUnitTests/index.cshtml.
 * Just put your tests into js files in /QUnitTests folder. The test runner scans for all of them.
 * Feel free to rename QUnitTests testing folder to anything you like.
 *
 * Please send any suggestions to improve that package and the runner.
 *
 * (c) 2012, Leonid Shirmanov
 * http://www.shirmanov.com
 *
 * Includes QUnit 1.3.0pre javascript testing framework
 * http://docs.jquery.com/QUnit
 *
 * Thanks to Phil Haack for his attempts to infuse technology and software development with humor and a pragmatic eye.
 * http://haacked.com/archive/2011/12/10/using-qunit-with-razor-layouts.aspx
 *
 * Works best with QUnit tests support in Jetbrains Resharper 6.x
 * http://blogs.jetbrains.com/dotnet/2011/03/resharper-6-introduces-support-for-javascript-unit-testing/
 *
 * Date: January, 29th 2012
 *@
@{
    // make use of SortedSet to avoid duplicate items being inserted
    SortedSet<string> filesUnderTest = new SortedSet<string>();
    SortedSet<string> testFiles = new SortedSet<string>();

    // find all .js files in folder
    var javascriptFileNames = from path in Directory.GetFiles(Server.MapPath("./"), "*.js")
        let fileName = Path.GetFileName(path)
    select fileName;

    string rawUrl = Request.RawUrl;

    // read and parse each js file to find <reference> xml comment tag which targets to js file inder test
    // the same technic is used in JetBrains Resharper so we make both test runners compatible
    foreach (string filename in javascriptFileNames)
    {
        string testFile = string.Format("{0}{1}", rawUrl, filename);
        testFiles.Add(testFile);
        
        foreach (string line in File.ReadLines(Path.Combine(Server.MapPath("./"), filename)))
        {
            string[] words = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (words.Length > 2 && words[0].Equals(@"///", StringComparison.Ordinal) && words[1].Equals(@"<reference", StringComparison.Ordinal))
            {
              int first = line.IndexOf('"');
              int last = line.LastIndexOf('"');

              if (first > 0 && last > 0 && last > first)
              {
                  string codeFilePath = line.Substring(first + 1, last - first - 1);
                  filesUnderTest.Add(codeFilePath);
              }
            }

        }
    }
}
<!-- Files under test -->
@foreach (string file in filesUnderTest) {
    <script type="text/javascript" src="@file"></script>
}

<!-- QUnit Tests -->
@foreach (string file in testFiles) {
    <script type="text/javascript" src="@file"></script>
}